25. 将源文件限制为单个顶级类

      为了具体说明,请考虑下面源文件,其中只包含一个引用其他两个顶级类( 和 Dessert 类)的成员的 Main 类:

      现在假设在 Utensil.java 的源文件中同时定义了 UtensilDessert

      现在假设你不小心创建了另一个名为 Dessert.java 的源文件,它定义了相同的两个类:

      如果你足够幸运,使用命令 javac Main.java Dessert.java 编译程序,编译将失败,编译器会告诉你,你已经多次定义了类 和 Dessert。 这是因为编译器首先编译 Main.java,当它看到对 Utensil 的引用(它在 Dessert 的引用之前)时,它将在 Utensil.java 中查找这个类并找到 UtensilDessert。 当编译器在命令行上遇到 Dessert.java 时,它也将拉入该文件,导致它遇到 和 Dessert 的定义。

      解决这个问题很简单,将顶层类(如我们的例子中的 Utensil 和 )分割成单独的源文件。 如果试图将多个顶级类放入单个源文件中,请考虑使用静态成员类(详见第 24 条)作为将类拆分为单独的源文件的替代方法。 如果这些类从属于另一个类,那么将它们变成静态成员类通常是更好的选择,因为它提高了可读性,并且可以通过声明它们为私有(详见第 15 条)来减少类的可访问性。下面是我们的例子看起来如何使用静态成员类:

      这个教训很清楚:永远不要将多个顶级类或接口放在一个源文件中。 遵循这个规则保证在编译时不能有多个定义。 这又保证了编译生成的类文件以及生成的程序的行为与源文件传递给编译器的顺序无关。